#ifndef SOUND_H
#define SOUND_H

#include <string>
#include <thread>
#include <sstream>

#include <windows.h>

#include "config.h"

namespace Sound {       // 该名字空间负责播放声音

    using std::string;
    using std::ostringstream;
    using namespace std::this_thread;

    enum class Information { stop, pause, resume, none };

    struct Multy_bgm_error {};      // 只能播放一首背景音乐

    class Sound {       // Sound是一个声音
    public:
        explicit Sound(string file_name) : path{file_name} { }
        virtual void play() const = 0;      // 播放这个声音
        virtual ~Sound() { }
    protected:
        virtual void init_sound() = 0;      // 初始化这个声音
        void set_alias(string o_alias) { alias = o_alias; }
        string get_path() const { return path; }
        string get_alias() const { return alias; }
    private:
        string path;
        string alias;
    };

    class Bgm : public Sound {      // Bgm类是一首背景音乐
    public:
        explicit Bgm(string file_name =bgm_path) : Sound{file_name} { init_sound(); }
        void play() const override;     // 播放bgm
        static bool is_playing() { return bgm_is_playing; }
        static void pause() { send_message(Information::pause); }
        static void resume() { send_message(Information::resume); }
        static void stop() { send_message(Information::stop); }
        ~Bgm() override { stop(); }
    private:
        void init_sound() override;     // 初始化这个声音
        static void thread_play_bgm(string file_name, string alias);        // 需要在另一个线程中播放bgm，并一直持续此线程
        static void send_message(Information message);      // 发送信息
        static Information inform;
        static bool is_pause;
        static bool bgm_is_playing;
    };

    class Effect : public Sound {       // Effect类是一个音效
    public:
        explicit Effect(string file_name =bomb_sound_path) : Sound{file_name} { init_sound(); }
        void play() const override;     // 播放这个音效
    private:
        void init_sound() override;     // 初始化这个声音
        static void thread_play_effect(string file_name, string alias);     // 在另一个线程中播放声音，否则会阻塞主线程
        static int effect_num;
    };

};

#endif // SOUND_H
